#ifndef _LYJ_CONFIG_H_INCLUDE_
#define _LYJ_CONFIG_H_INCLUDE_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32

#define WIN32_NO_STATUS
#include <winsock2.h>
#include <ws2tcpip.h>   // for inet_pton,inet_ntop
#include <windows.h>
#undef WIN32_NO_STATUS
#else
#include <unistd.h>
#ifdef __APPLE__
#include <machine/endian.h>
#else
#include <endian.h>
#endif
#include <arpa/inet.h>
#endif
#include "lyj_types.h"

#ifdef _WIN32
#define lyj_inline	__inline
#else
#define lyj_inline	inline
#endif

#ifdef _WIN32
#define lyj_thread_local __declspec(thread)
#else
#define lyj_thread_local __thread
#endif


#if defined(_WIN32)
#if defined(LYJ_DLL)
#ifdef LYJ_DLL_BUILD
#define lyj_dll_api __declspec(dllexport)
#else
#define lyj_dll_api __declspec(dllimport)
#endif
#else
#define lyj_dll_api
#endif
#else
#define lyj_dll_api __attribute__ ((visibility ("default")))
#endif

#ifdef __cplusplus
#define LYJ_EXTERN_C_BEGIN extern "C" {
#define LYJ_EXTERN_C_END   }
#else
#define LYJ_EXTERN_C_BEGIN 
#define LYJ_EXTERN_C_END   
#endif

#define lyj_cdecl	


#ifdef __GNUC__
#define lyj_builtin_expect(exp, c) __builtin_expect(exp, c)
#else
#define lyj_builtin_expect(exp, c) (exp)
#endif
#define lyj_likely(x) lyj_builtin_expect(!!(x), 1)    
#define lyj_unlikely(x) lyj_builtin_expect(!!(x), 0)

#define lyj_calloc(nmemb, size)          calloc((size_t)(nmemb), (size_t)(size))
#define lyj_malloc(size)                 malloc((size_t)(size))
#define lyj_type_malloc(type)            (type *)malloc((size_t)(sizeof(type)))
#define lyj_mtype_malloc(type, count)    (type *)malloc((size_t)(sizeof(type) * (count)))
#define lyj_free(ptr)                    free((void *)(ptr))
#define lyj_realloc(ptr, size)           realloc((void *)(ptr), (size_t)(size))
#define lyj_memset(s, c, n)              (void) memset((void *)(s), (int)(c), (size_t)(n))
#define lyj_memzero(s, n)                lyj_memset(s, 0, n)
#define lyj_type_memzero(s)              lyj_memset(s, 0, sizeof(*(s)))
#define lyj_mtype_memzero(s, count)      lyj_memset(s, 0, sizeof(*(s)) * (count))
#define lyj_memcpy(dest, src, n)         (void) memcpy(dest, src, (size_t)(n))

#define lyj_abs(value)       (((value) >= 0) ? (value) : - (value))
#define lyj_max(val1, val2)  ((val1) < (val2) ? (val2) : (val1))
#define lyj_min(val1, val2)  ((val1) > (val2) ? (val2) : (val1))
#ifdef _WIN32
#define lyj_sleep(seconds) Sleep(seconds * 1000)
#define lyj_usleep(usec) Sleep(usec / 1000)
#define lyj_atoll(nptr) (lyj_int64_t)_atoi64((const char *)(nptr))
#define lyj_strtoll(nptr, endptr, base) (lyj_int64_t)_strtoi64((const char *)(nptr), (char **)endptr, (int)base)

#define lyj_htons(host_16bits) (lyj_uint16_t) htons((u_short) (host_16bits))
#define lyj_ntohs(big_endian_16bits) (lyj_uint16_t) ntohs((u_short) (big_endian_16bits))

#define lyj_htonl(host_32bits) (lyj_uint32_t) htonl((u_long) host_32bits)
#define lyj_ntohl(big_endian_32bits) (lyj_uint32_t) ntohl((u_long) big_endian_32bits)

#define lyj_htonll(host_64bits) (lyj_uint64_t) htonll((unsigned __int64) host_64bits)
#define lyj_ntohll(big_endian_64bits) (lyj_uint64_t) ntohll((unsigned __int64) big_endian_64bits)


#else
#define lyj_sleep(seconds) sleep(seconds)
#define lyj_usleep(usec) usleep((useconds_t)usec)
#define lyj_atoll(nptr) (lyj_int64_t)atoll((const char *)(nptr))
#define lyj_strtoll(nptr, endptr, base) (lyj_int64_t)strtoll((const char *)(nptr), (char **)endptr, (int)base)

#define lyj_htons(host_16bits) (lyj_uint16_t) htobe16((uint16_t) (host_16bits))
#define lyj_ntohs(big_endian_16bits) (lyj_uint16_t) be16toh((uint16_t) (big_endian_16bits))

#define lyj_htonl(host_32bits) (lyj_uint32_t) htobe32((uint32_t) host_32bits)
#define lyj_ntohl(big_endian_32bits) (lyj_uint32_t) be32toh((uint32_t) big_endian_32bits)

#define lyj_htonll(host_64bits) (lyj_uint64_t) htobe64((uint64_t) host_64bits)
#define lyj_ntohll(big_endian_64bits) (lyj_uint64_t) be64toh((uint64_t) big_endian_64bits)
#endif
#ifndef NULL
#define NULL 0
#endif

#define LYJ_STD_PRINT

#if ((__GNU__ == 2) && (__GNUC_MINOR__ < 8))
#define LYJ_MAX_UINT32_VALUE  ((lyj_uint32_t) 0xffffffffLL)
#else
#define LYJ_MAX_UINT32_VALUE  ((lyj_uint32_t) 0xffffffff)
#endif

#define LYJ_MAX_INT32_VALUE   ((lyj_int32_t) 0x7fffffff)
#define LYJ_MIN_INT32_VALUE   (-0x7fffffff - 1)  

#define LYJ_INT32_LEN   (sizeof("-2147483648") - 1)
#define LYJ_INT64_LEN   (sizeof("-9223372036854775808") - 1)

#endif /* _LYJ_CONFIG_H_INCLUDE_ */
